package com.tenebrous.jestic.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tenebrous.jestic.entity.TreeSerializable;
import com.tenebrous.jestic.mapper.ISuperMapper;
import lombok.Setter;
import org.apache.commons.lang.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 超级服务抽象类
 * @param <T>
 */
public abstract class SuperService<T> {

    /**
     * 超级mapper
     */
    @Setter
    private ISuperMapper<T> superMapper;

    /**
     * 抽象方法，用于子类实现SuperMapper<T>传值
     */
    protected abstract void setSuperMapper();

    /**
     * 保存记录
     * @param item 记录对象
     * @return 返回受影响的记录数
     */
    public int save(T item){

        return this.superMapper.insert(item);
    }

    /**
     *  保存记录
     * @param items 记录集合
     * @return 返回受影响的记录数
     */
    @Transactional
    public int save(Collection<T> items){
        int i = 0;
        for (T t : items) {
            i += this.superMapper.insert(t);
        }
        return i;
    }

    /**
     * 保存记录，忽略null属性
     * @param item 记录对象
     * @return 返回受影响的记录数
     */
    public int saveSelective(T item){

        return this.superMapper.insertSelective(item);
    }

    /**
     *  保存记录，忽略null属性
     * @param items 记录集合
     * @return 返回受影响的记录数
     */
    @Transactional
    public int saveSelective(Collection<T> items){

        int i = 0;
        for (T t : items) {
            i += this.superMapper.insertSelective(t);
        }
        return i;
    }

    /**
     * 删除记录
     * @param id 记录主键
     * @return 返回受影响的记录数
     */
    public int deleteByPrimaryKey( Serializable id){
        return this.superMapper.deleteByPrimaryKey(id);
    }

    /**
     * 删除记录
     * @param ids 记录主键拼接字符串，用逗号分隔。如："123,456"
     * @return 返回受影响的记录数
     */
    @Transactional
    public int deleteByIds(String ids){
        return this.deleteByIds(ids.split(","));
    }

    /**
     * 删除记录
     * @param ids 记录主键集合
     * @return 返回受影响的记录数
     */
    @Transactional
    public int deleteByIds(String[] ids){
        int i = 0;
        for (String id: ids) {
            i += this.superMapper.deleteByPrimaryKey(id);
        }
        return i;
    }

    /**
     * 更新记录
     * @param item 记录对象
     * @return 返回受影响的记录数
     */
    public int update(T item){

        return this.superMapper.updateByPrimaryKey(item);
    }

    /**
     * 更新记录
     * @param items 记录集合
     * @return 返回受影响的记录数
     */
    @Transactional
    public int update(Collection<T> items){

        int i = 0;
        for (T t : items) {
            i += this.superMapper.updateByPrimaryKey(t);
        }
        return i;
    }

    /**
     *  更新记录，忽略null属性
     * @param item 记录对象
     * @return 返回受影响的记录数
     */
    public int updateSelective(T item){

        return this.superMapper.updateByPrimaryKeySelective(item);
    }

    /**
     * 更新记录
     * @param items 记录集合
     * @return 返回受影响的记录数
     */
    @Transactional
    public int updateSelective(Collection<T> items){

        int i = 0;
        for (T t : items) {
            i += this.superMapper.updateByPrimaryKeySelective(t);
        }
        return i;
    }

    /**
     * 查询记录
     * @param id 记录主键
     * @return 返回唯一记录或null
     */
    public T selectByPrimaryKey( Serializable id){
        return this.superMapper.selectByPrimaryKey(id);
    }

    /**
     * 查询记录
     * @param ids 记录主键集合
     * @return 返回记录集合或空集合
     */
    public List<T> queryByIds(@NotEmpty String[] ids){

        return this.superMapper.selectByIds(StringUtils.join(ids, ","));
    }

    /**
     * 查询记录
     *
     * @param item
     * @return
     */
    public T queryObj(@NotEmpty T item){
        return this.superMapper.selectOne(item);
    }

    /**
     * 查询记录
     *
     * @param item
     * @return
     */
    public List<T> queryListByObj(@NotEmpty T item){
        return this.superMapper.select(item);
    }

    /**
     * 查询记录
     * @return 返回记录集或空集合
     */
    public List<T> queryAll(){
        return this.superMapper.selectAll();
    }

    /**
     * 分页查询记录
     * @param pageIndex 当前页
     * @param pageSize 每页显示记录数
     * @return 返回记录集或空集合
     */
    public PageInfo<T> queryPagingList(Integer pageIndex, Integer pageSize) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> this.superMapper.selectAll());
    }

    public List<TreeSerializable> buildTree( List<TreeSerializable> list, String pid){
        if(Objects.isNull(list) || list.isEmpty()){
            return new ArrayList<>();
        }
        //获取根列表
        List<TreeSerializable> roots = list.stream().filter(e -> e.getPid().equals(pid)).collect(Collectors.toList());
        if(roots.isEmpty()){
            return new ArrayList<>();
        }
        //为根设置子元素
        for (TreeSerializable root : roots) {
            List<TreeSerializable> children = this.buildTree(list, root.getId());
            root.setChildren(children);
        }
        return roots;
    }
}
